import {ReactComponent} from "../../class/ReactComponent";
import {TableArticleList} from "../../../common/class/TableArticleList";
import React from "react";
import {PaginationConfig} from "antd/es/pagination";
import {Button, message, Table, Icon} from "antd";
import {ColumnProps, TableRowSelection} from "antd/lib/table";
import {sortString} from "../../../common/function/stringFunc";
import {mixedObj} from "../../../common/function/objFunc";
import {floatVal} from "../../../common/function/numFunc";
import {SpinProps} from "antd/lib/spin";
import {openURLInExplorer} from "../../../common/function/appFunc";

const tableArticleList = new TableArticleList();

export namespace ArticlesTable {
    export interface Props extends ReactComponent.Props {
        bookId: number;
        onEditItem?: (row: TableArticleList.Data) => void;
    }
    export interface State extends ReactComponent.State {
        filteredList: TableArticleList.Data[];
        pagination: false | PaginationConfig;
        loading: boolean | SpinProps;
    }
}

export class ArticlesTable extends ReactComponent<ArticlesTable.Props, ArticlesTable.State> {
    public readonly state: ArticlesTable.State = {
        pagination: false,
        filteredList: [],
        loading: false,
    };
    protected selectedIds: number[] = [];
    protected list: TableArticleList.Data[];
    public render() {
        return (
            <div className={this.getClsName("articles-table-component")}>
                <Table
                    scroll={{ y: 240 }}
                    loading={this.state.loading}
                    pagination={this.state.pagination}
                    rowSelection={this.getRowSelectionObj(this)}
                    rowKey="id"
                    columns={this.getCols()}
                    dataSource={this.state.filteredList}
                />
            </div>
        );
    }
    public componentDidMount() {
        this.refreshList();
    }
    public componentDidUpdate(
        prevProps: Readonly<ArticlesTable.Props>,
        prevState: Readonly<ArticlesTable.State>,
        snapshot?: any
    ): void {
        if (this.props.bookId !== prevProps.bookId) {
            this.refreshList();
        }
    }
    public getSelectedIdList(): number[] {
        return this.selectedIds;
    }
    public switchLoading(loading?: boolean) {
        let nextLoadState = !this.state.loading;
        if (loading != null) {
           nextLoadState = loading;
        }
        if (nextLoadState) {
            this.showLoading();
        } else {
            this.hideLoading();
        }
    }
    public showLoading() {
        this.setState({
            loading: true,
        });
    }
    public hideLoading() {
        this.setState({
            loading: false,
        });
    }
    public refreshList() {
        const bookId = this.props.bookId;
        if (!bookId) {
            return false;
        }
        this.showLoading();
        tableArticleList
            .select()
            .where({
                book_id: bookId,
            })
            .orderBy("article_index")
            .findAll()
            .then((rows) => {
                this.list = rows as any as TableArticleList.Data[];
                this.refreshFilterList();
            }).catch((err) => {
                message.error("获取列表信息出错");
                console.error(err);
            })
            .finally(() => {
                this.hideLoading();
            });
    }
    public delByIdList(idList: number[]) {
        if (idList.length) {
            tableArticleList.deleteByKeyList(idList).then(() => {
                this.refreshList();
            }).catch((err) => {
                message.error("删除出错");
                console.error(err);
            });
        }
    }
    protected refreshFilterList() {
        const list = this.list;
        this.setState({
            filteredList: list,
        });
    }
    protected getRowSelectionObj(context: this): TableRowSelection<TableArticleList.Data> {
        const self = this;
        return {
            onChange(selectedRowKeys: string[] | number[]) {
                // context.updateSelectedRows(selectedRowKeys, rows);
                self.selectedIds = selectedRowKeys as number[];
            },
        };
    }
    protected getCols(): Array<ColumnProps<TableArticleList.Data>> {
        return [
            this.getColName(),
            this.getColOriginURL(),
            this.getColMethod(),
            this.getColLocalized(),
            this.getColOperator(),
        ];
    }
    protected getColOperator(): ColumnProps<TableArticleList.Data> {
        const context = this;
        return {
            title: "操作",
            key: "operator",
            render(text: any, row) {
                return (
                    <Button type="primary" onClick={() => context.clickEditBtn(row)}>
                        <Icon type="edit"/>
                        <span>编辑</span>
                    </Button>
                );
            },
        };
    }
    protected clickEditBtn(row: TableArticleList.Data) {
        if (typeof this.props.onEditItem === "function") {
            this.props.onEditItem(row);
        }
    }
    protected getColOriginURL(): ColumnProps<TableArticleList.Data> {
        const self = this;
        return this.getColOf("origin_url", "网址", {
            render(url) {
                return (<div className="clickable" onClick={self.onClickURL.bind(this, url)}>{url}</div>);
            },
        });
    }
    protected onClickURL(url: string) {
        openURLInExplorer(url);
    }
    protected getColLocalized(): ColumnProps<TableArticleList.Data> {
        return this.getColOf("localized", "本地/网络", {
            render(text) {
                const num = floatVal(text, 0);
                if (num) {
                    return "本地";
                }
                return "网络";
            },
        });
    }
    protected getColMethod(): ColumnProps<TableArticleList.Data> {
        return this.getColOf("download_method", "下载方法");
    }
    protected getColName(): ColumnProps<TableArticleList.Data> {
        return {
            title: "章节名",
            key: "name",
            dataIndex: "name",
            className: "col-name",
            sorter(itemA, itemB) {
                return itemB.article_index - itemA.article_index;
            },
            defaultSortOrder: "ascend",
        };
    }
    protected getColOf(
        key: keyof TableArticleList.Data,
        title: string,
        otherOptions: ColumnProps<TableArticleList.Data> = {}
    ): ColumnProps<TableArticleList.Data> {
        return mixedObj({
            key,
            dataIndex: key,
            title,
            className: "col-" + key,
        }, otherOptions);
    }
}
